package cn.st4rlight.util.convert.base;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import cn.st4rlight.util.convert.BigDecimalConverter;
import cn.st4rlight.util.convert.BigIntegerConverter;
import cn.st4rlight.util.convert.BooleanConverter;
import cn.st4rlight.util.convert.ByteArrayConverter;
import cn.st4rlight.util.convert.ByteConverter;
import cn.st4rlight.util.convert.DoubleConverter;
import cn.st4rlight.util.convert.FloatConverter;
import cn.st4rlight.util.convert.IntegerConverter;
import cn.st4rlight.util.convert.LongConverter;
import cn.st4rlight.util.convert.ShortConverter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * @author st4rlight <st4rlight@163.com>
 * Created on 2025-10-18
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ConvertService {

    // 类型 --> 对应的转换器
    private static final Map<Class<?>, IConverter<?>> CONVERTER_MAP = new HashMap<>();
    static {
        register(new BooleanConverter(), Boolean.class, boolean.class);
        register(new IntegerConverter(), Integer.class, int.class);
        register(new LongConverter(), Long.class, long.class);
        register(new DoubleConverter(), Double.class, double.class);
        register(new FloatConverter(), Float.class, float.class);
        register(new ShortConverter(), Short.class, short.class);

        register(new BigDecimalConverter(), BigDecimal.class);
        register(new BigIntegerConverter(), BigInteger.class);
        register(new ByteConverter(), byte.class, Byte.class);
        register(new ByteArrayConverter(), byte[].class, Byte[].class);
    }

    /**
     * 注册类型转换器
     */
    private static void register(IConverter<?> converter, Class<?>... classes) {
        for (Class<?> clazz : classes) {
            CONVERTER_MAP.put(clazz, converter);
        }
    }

    /**
     * 将对象转换为指定类型，若转换失败，则返回null
     */
    public static Object convert(Object value, Class<?> toType) {
        if (Objects.isNull(value) || Objects.isNull(toType)) {
            return null;
        }
        if (String.class.equals(value.getClass())
                && StringUtils.isBlank((String) value)
                && !String.class.equals(toType)) {
            return null;
        }

        if (value.getClass().isAssignableFrom(toType)) {
            return value;
        }
        Class<?>[] interfaces = value.getClass().getInterfaces();
        if (Serializable.class.equals(toType) && ArrayUtils.contains(interfaces, Serializable.class)) {
            return value;
        }

        String valueString = StringUtils.trimToEmpty(value.toString());
        if (valueString.isEmpty()) {
            return null;
        }
        IConverter<?> converter = CONVERTER_MAP.get(toType);
        if (converter != null) {
            return converter.convert(valueString);
        } else {
            return null;
        }
    }

    /**
     * 获取基本类型的默认值
     */
    public static Object getPrimitiveDefaultValue(Class<?> paraClass) {
        if (paraClass == int.class
                || paraClass == long.class
                || paraClass == float.class
                || paraClass == double.class) {
            return 0;
        } else if (paraClass == boolean.class) {
            return Boolean.FALSE;
        } else if (paraClass == short.class) {
            return (short) 0;
        } else if (paraClass == byte.class) {
            return (byte) 0;
        } else if (paraClass == char.class) {
            return '\u0000';
        } else if (paraClass == String.class) {
            return "";
        } else {
            // 不存在这种类型
            return null;
        }
    }
}
